本來今天是打算寫點心得就水過去了,但我一個朋友突然提了一個蠻有趣的點子:那就是教大家怎麼製作一個程式語言。
沒錯,在這最後一天,來一個超級衝刺吧!
說是自製程式語言,時間其實也不夠,所以今天我要帶著大家實作的是一個叫做brainfuck的程式語言的直譯器。
我們開發所使用的語言是Kotlin,所以拿出你們的Intellij IDEA吧!
首先是BrainFuck的介紹,BF是一個符合圖靈完備的程式語言,但他只使用8個字母來完成所有的程式。
你可以先想像有一個256格的char陣列a,跟一個叫做p的int,指向第零格。
| 符號 | 對應的程式碼 | 
|---|---|
| + | a[p]++ | 
| - | a[p]— | 
| [ | 如果a[p]==0就跳到後面的] | 
| ] | 如果a[p]!=0就回到前面的[ | 
| < | p++ | 
| > | p-- | 
| , | 輸入a[p] | 
| . | 輸出a[p] | 
首先我們先做一個Model來完成我們的運算部分。
class Model{
    private var array = Array<Char>(256){Char(0)}
    private var p = 0
}
首先是屬性的部分,我們的要維護一個array,一個p。
接下來是method的部分,我們簡單一點,寫一個fun run(cmd:String) ,參數就是我們的BF程式碼。
fun run(cmd:String){
        var cmd_index = 0
        
}
然後是遍歷我們的程式碼,並判斷他是什麼指令,我們使用kotlin的when語法。
fun run(cmd:String){
        cmd_index = 0
        while(cmd_index < cmd.length){
            when(cmd[cmd_index]){
                ',' -> //dosomething
                '.' -> //dosomething
                '+' -> //dosomething
                '-' -> //dosomething
                '>' -> //dosomething
                '<' -> //dosomething
                '[' -> //dosomething
                ']' -> //dosomething
            }
            cmd_index++
        }
    }
其實正常應該是要切成不同的method下去使用啦,不過由於這次的任務太簡單了,所以就算了。
來完成任務吧!
class Model{
    private var array = Array<Char>(256){Char(0)}
    private var p = 0
    fun run(cmd:String){
        var cmd_index = 0
        while(cmd_index < cmd.length){
            when(cmd[cmd_index]){
                ',' -> readln()
                '.' -> print(array[p])
                '+' -> array[p]++
                '-' -> array[p]--
                '>' -> p++
                '<' -> p--
                '[' -> {
                    if(array[p]==Char(0)){
                        while(cmd[cmd_index]!=']'){
                            cmd_index++
                        }
                    }
                }
                ']' -> {
                    if(array[p]!=Char(0)){
                        while(cmd[cmd_index]!='['){
                            cmd_index--
                        }
                    }
                }
            }
            cmd_index++
        }
    }
}
如此簡單,我們的Model就完成了。
接下來就是我們的main函式啦,我們要來實作輸入的部分。
fun main(args: Array<String>) {
    val m = Model()
    val cmd = readln()
    m.run(cmd)
}
完成,最後輸入一段hello world,看看是否可以正常執行吧!
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
輸出結果
Hello World!
總算是結束了這三十天的旅程,我介紹了各種的宗教戰爭,也介紹了很多有趣的東西,不知道各位是否喜歡呢?
今年總算不像去年一樣,超級半途而廢,在最後一天忘記上傳內容。
這次的題目元的真的輕鬆有趣,每一個題目都讓我想到很多事情,一路上資工的各種方向算是都接觸過,所以很多東西感受很深,比如剛開始寫C++的時候我其實是下放的,是後來寫了Java才真的覺得下放很醜然後改成不下放等等。
感謝各位30天的陪伴,明年的題目還沒想好,但應該還是會參賽吧!
所以,各位明年見啦~~
最後一個meme,一起嘲笑去年沒寫完的我吧!